VBNET:ScriptingisthepastPart3
How to: Scripting is the past Native code is the future! Part 3 of 3 Author: Created by: X Web: http://www.createdbyx.com/ Date: December 2, 2004 This new scripting application is based on the previous examples but has been rewritten with the fallowing changes ... 1: The application now loads and compiles the script from a file. 2: The script now implements a interface called ICommunications. This interface is located in the host application and is used to pass messages back and fourth between the script and the host application without the need to use reflection. The code is pretty self explanatory and easy enough to read through and understand. I hope this example app helps to inspire developers out there. Sample Code 'Created by: X 'Copyright: Created by: X 'Web: http://www.createdbyx.com/ 'Date: January 28, 2004 ' Public Interface ICommunications Sub SendMessage(ByVal Msg As Integer, ByVal Params As Collections.Specialized.StringCollection) Sub SetMessageOutput(ByVal MO As MessageSend) Sub TestIt() Delegate Sub MessageSend(ByVal Msg As Integer, ByVal Params As Collections.Specialized.StringCollection) End Interface Public Module General Public Sub Main() Dim Assm As System.Reflection.Assembly ' now compile the script using codedom Console.Write("Compiling script ...") Assm = CompileScript() If Not Assm Is Nothing Then Console.Write(" Done.") Console.WriteLine() Console.WriteLine("Running script ...") Console.WriteLine("---------------------------------------------------------") ' we try to create the obj rather than getting it's type reference Dim Obj As Object = Assm.CreateInstance("Test", True) ' check if the object implements the ICommunications interface If TypeOf Obj Is ICommunications Then Dim IObj As ICommunications = Obj Dim P As New Collections.Specialized.StringCollection() ' send a message to the script P.Add("ParamA") P.Add("ParamB") P.Add("ParamC") IObj.SendMessage(6, P) ' Give the script a method to call. Try commenting this line out to see what happens! IObj.SetMessageOutput(AddressOf RecieveMessages) ' Call the TestIt method IObj.TestIt() Else Console.WriteLine("ERROR: Test class does not implement ICommunications interface.") End If End If Console.WriteLine() Console.WriteLine("---------------------------------------------------------") Console.WriteLine("Press enter to quit...") Console.ReadLine() End Sub Public Sub RecieveMessages(ByVal Msg As Integer, ByVal Params As Collections.Specialized.StringCollection) Dim idx As Integer Console.WriteLine("Scripting Host: Message recieved. MSG: " & Msg.ToString & " - Param count: " & Params.Count.ToString) For idx = 0 To Params.Count - 1 Console.WriteLine("Param " & idx.ToString & ": " & Params(idx)) Next Console.WriteLine() End Sub Public Function CompileScript() As Reflection.Assembly Dim CodeP As New Microsoft.VisualBasic.VBCodeProvider() Dim Com As CodeDom.Compiler.ICodeCompiler Dim Param As New CodeDom.Compiler.CompilerParameters() Dim Ret As CodeDom.Compiler.CompilerResults ' we do not want to generate a file Param.GenerateExecutable = False Param.GenerateInMemory = True ' get a reference to the compiler Com = CodeP.CreateCompiler() ' Add the System.dll assembly so that the compiled script can write out to the console. Param.ReferencedAssemblies.Add("System.dll") ' We also need to add the host application because that is where the ICommunications interface is. Param.ReferencedAssemblies.Add("Scripting.exe") ' Now we compile the script. Ret = Com.CompileAssemblyFromFile(Param, "..\Script.vb") ' If there were errors during compile tell user. If Ret.Errors.HasErrors Then Console.WriteLine() Console.WriteLine() Console.WriteLine(Ret.Errors.Item(0).ErrorText) Return Nothing End If Return Ret.CompiledAssembly End Function End Module Sample Script Code The fallowing is the code for the "Script.vb" file. 'Created by: X 'Copyright: Created by: X 'Web: http://www.createdbyx.com/ 'Date: February 4, 2004 ' Imports System Public Class Test Implements Scripting.ICommunications Private mobjMO As Scripting.ICommunications.MessageSend Public Sub TestIt() Implements Scripting.ICommunications.TestIt If Not mobjMO Is Nothing Then Dim P As New Collections.Specialized.StringCollection() P.Add("Param1") P.Add("Param2") mobjMO(10, P) Else Console.WriteLine("Test class: No message output delegate has been setup.") End If End Sub Public Sub SendMessage(ByVal Msg As Integer, ByVal Params As System.Collections.Specialized.StringCollection) Implements Scripting.ICommunications.SendMessage Dim idx As Integer Console.WriteLine("Test class: Message recieved. MSG: " & Msg.ToString & " - Param count: " & Params.Count.ToString) For idx = 0 To Params.Count - 1 Console.WriteLine("Param " & idx.ToString & ": " & Params(idx)) Next Console.WriteLine() End Sub Public Sub SetMessageOutput(ByVal MO As Scripting.ICommunications.MessageSend) Implements Scripting.ICommunications.SetMessageOutput mobjMO = MO End Sub End Class